package com.clp.protocol.iec104.apdu.apci;

import com.clp.protocol.core.pdu.nbytepdu.BaseNBytePduClip;
import com.clp.protocol.core.pdu.ByteToStringFormat;
import com.clp.protocol.core.utils.ByteUtil;
import io.netty.buffer.ByteBuf;
import lombok.*;

import java.util.Objects;
import java.util.function.Consumer;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ICtrlArea extends CtrlArea<ICtrlArea> {
    /**
     * 发送序号
     */
    private int sendSeq;
    /**
     * 接收序号
     */
    private int recvSeq;

    @Override
    public ICtrlArea refreshFrom(ByteBuf buf) {
        this.sendSeq = (buf.readShortLE() & 0xFFFF) >> 1;
        this.recvSeq = (buf.readShortLE() & 0xFFFF) >> 1;
        return this;
    }

    @Override
    public boolean isValid() {
        return sendSeq >= 0 && recvSeq >= 0;
    }

    @Override
    public void writeBytesTo(ByteBuf buf) {
        buf.writeShortLE(sendSeq << 1);
        buf.writeShortLE(recvSeq << 1);
    }

    @Override
    public void writeFormattedByteStringsTo(StringBuilder sb, String frameClipBytesSeparator, String byteSeparator, ByteToStringFormat byteFormat) {
        byte[] sendSeqBytes = ByteUtil.intToBytes2LE(sendSeq << 1);
        sb.append(byteFormat.format(sendSeqBytes[0]));
        for (int i = 1; i < sendSeqBytes.length; i++) {
            sb.append(byteSeparator).append(byteFormat.format(sendSeqBytes[i]));
        }
        byte[] recvSeqBytes = ByteUtil.intToBytes2LE(recvSeq << 1);
        for (byte recvSeqByte : recvSeqBytes) {
            sb.append(byteSeparator).append(byteFormat.format(recvSeqByte));
        }
    }

    @Override
    public void writeSimpleDescriptionTo(StringBuilder sb) {
        sb.append("[").append(sendSeq).append(", ").append(recvSeq).append("]");
    }

    @Override
    public void writeDetailDescriptionTo(StringBuilder sb) {
        sb.append("发送序号：").append(sendSeq).append(", 接收序号：").append(recvSeq);
    }

    @Override
    protected void forEachOneLevelChild(Consumer<BaseNBytePduClip<?>> consumer) {

    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ICtrlArea that = (ICtrlArea) o;
        return sendSeq == that.sendSeq && recvSeq == that.recvSeq;
    }

    @Override
    public int hashCode() {
        return Objects.hash(sendSeq, recvSeq);
    }
}
